home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Panorama / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].zip / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].adf / WarpText2.0 / WarpText.asm < prev    next >
Assembly Source File  |  1987-07-19  |  22KB  |  547 lines

  1. * --------------------------------------------------------------------------
  2. * WarpText.asm                   Version 2.0                      Bill Kelly
  3. *                                                                 07/07/87
  4. *
  5. * Copyright 1987 by Bill W. Kelly.
  6. *
  7.  
  8.     XDEF InitWarpInfo
  9.     XDEF GotoXY
  10.     XDEF GetXY
  11.     XDEF WarpText
  12.     XDEF SetupFont
  13.     XDEF NewWarp
  14.     XDEF XORCursor
  15.  
  16.             NOLIST  ; I don't want to see all of this junque...
  17.  
  18.                INCLUDE "graphics/text.i"
  19.                INCLUDE "graphics/gfx.i"
  20.                INCLUDE "graphics/WarpText.i"
  21.  
  22.             LIST    ; Turn listing back on...
  23.  
  24.             CODE    ; WarpText begins...
  25.  
  26. * ==========================================================================
  27. *
  28. *         |      __          ___                   __     __     |
  29. *         |     /  \   /     /  \     /   /  /|   /  \   /  \    |
  30. *        \|/   /   /  /     /   /    / / /  /_|  /\__/  /\__/   \|/
  31. *         V    \__/  /___  /___/     \/\/  /  | /   \  /         V
  32. *
  33. * --------------------------------------------------------------------------
  34. * InitWarpInfo:
  35. * -------------
  36. *
  37. * INITWARPINFO NEEDS:
  38. *
  39. * a0 - Pointer to an instance of the WarpInfo structure, with the following
  40. *      fields initialized:
  41. *
  42. *   wi_TextFont:    Pointer to an open font.  (I.e. what OpenFont() returns
  43. *                   to you, other than NULL.)
  44. *   wi_BitMap:      Pointer to an initialized, 'working' BitMap structure.
  45. *                   (E.g. Open a window.  Get the pointer to the screen
  46. *                   out of wd_WScreen.  From there the BitMap structure is
  47. *                   at sc_BitMap, which is an offset, not a pointer, into
  48. *                   the Screen structure.)
  49. *   wi_WhichPlane:  Which bitplane you want the routine to draw into.
  50. *                   Numbering begins at zero.  On the Workbench screen
  51. *                   (or any two-bitplane screen) the possible numbers for
  52. *                   wi_WhichPlane are 0 and 1.
  53. *   wi_Left:        Left edge of the 'window' (in character locations)
  54. *                   you want the routine to write into.
  55. *   wi_Top:         Top edge of the 'window' in character locations.
  56. *   wi_Width:       Width of 'window' (also on character locations).
  57. *   wi_Height:      Height of 'window' -- guess what? Character locations.
  58. *
  59. * REGISTER USAGE FOR INITWARPINFO:
  60. *
  61. * d0 - Left, Top, Width, Height, etc.
  62. * d1 - wi_Modulo
  63. * d2 - Scratch
  64. * d3 - Y size of font
  65. * d4 - Scratch
  66. *
  67. * a0 - Pointer to WarpInfo structure with above fields initialized.
  68. * a1 - Addr of top of bitplane, wi_WindowTop, etc.
  69. * a2 - Scratch
  70. *
  71.  
  72. InitWarpInfo:   movem.l d0-d4/a1-a2,-(sp)
  73.  
  74.                 moveq   #0,d4                   ; Clear scratch.
  75.                 move.w  d4,wi_CurX(a0)          ; Store it in WarpInfo.
  76.  
  77.                 move.w  wi_Width(a0),wi_LastX(a0)  ; Max X position.
  78.                 sub.w   #1,wi_LastX(a0)         ; make it 0-relative.
  79.  
  80.                 move.l  wi_BitMap(a0),a1        ; Get some stuff from bmap.
  81.  
  82.                 moveq   #0,d2
  83.                 move.w  bm_BytesPerRow(a1),d2   ; #bytes per row in d2
  84.                 move.w  d2,wi_BPMod(a0)         ; #bytes per row->wi_BPMod
  85.  
  86.                 move.w  wi_WhichPlane(a0),d4    ; Get bitplane#.
  87.                 asl.l   #2,d4                   ; Multiply plane# by four.
  88.                 move.l  bm_Planes(a1,d4.l),a1   ; Get address of bitplane.
  89.  
  90.                 moveq   #0,d3
  91.                 move.l  wi_TextFont(a0),a2
  92.                 move.w  tf_YSize(a2),d3         ; Get YSize of font.
  93.  
  94.                 moveq   #0,d1
  95.                 move.l  d2,d1                   ; Copy bytesperrow to d1.
  96.                 mulu.w  d3,d1                   ; YSize*BytesPerRow.
  97.                 move.w  d1,wi_Modulo(a0)        ; Store it in WarpInfo.
  98.  
  99.                 moveq   #0,d4
  100.                 move.l  d1,d4                   ; Copy wi_modulo to scratch.
  101.                 mulu.w  wi_Top(a0),d4           ; Mul by Y offset.
  102.                 add.w   wi_Left(a0),d4          ; Add X offset.
  103.  
  104.                 move.l  a1,a2                   ; BPlane addr to scratch.
  105.                 add.l   d4,a2                   ; Add offset to btpln addr.
  106.                 move.l  a2,wi_WindowTop(a0)     ; Stick in WarpInfo.
  107.                 move.l  a2,wi_CurLine(a0)       ; Stick in WarpInfo.
  108.  
  109.                 moveq   #0,d2
  110.                 move.w  wi_Top(a0),d2           ; Copy Y top to scratch.
  111.                 add.w   wi_Height(a0),d2        ; Add Y height to Y top.
  112.                 move.l  d1,d4                   ; Copy wi_modulo to scratch.
  113.                 mulu.w  d2,d4                   ; Mul by Y offset.
  114.                 add.w   wi_Left(a0),d4          ; Add X offset.
  115.  
  116.                 move.l  a1,a2                   ; BPlane addr to scratch.
  117.                 add.l   d4,a2                   ; Add offset to btpln addr.
  118.                 move.l  a2,wi_LastLine(a0)      ; Stick in WarpInfo.
  119.  
  120.                 movem.l (sp)+,d0-d4/a1-a2
  121.  
  122.                 rts
  123. *
  124. * --------------------------------------------------------------------------
  125.  
  126. * --------------------------------------------------------------------------
  127. * GotoXY:
  128. * -------
  129. *
  130. * GOTOXY NEEDS:
  131. *
  132. * d0 - New X position.          \ All regs. but d1 preserved,
  133. * d1 - New Y position.
  134. *
  135. * a0 - Pointer to initialized WarpInfo structure.
  136. *
  137. * NOTE: These positions are given in character locations, like everything
  138. *       else...  The positions are relative to the 'window' you have
  139. *       defined using InitWarpInfo.  Position 0,0 is the character in the
  140. *       top left corner of the window.
  141. *       This routine does no error checking.  (You're supposed to know
  142. *       how big your window is...)
  143. *
  144.  
  145. GotoXY:         move.w  d0,wi_CurX(a0)      ; Set new X position.
  146.  
  147.                 mulu.w  wi_Modulo(a0),d1    ; Make Y an offset into window
  148.                 add.l   wi_WindowTop(a0),d1 ; Add this offset to the window
  149.                 move.l  d1,wi_CurLine(a0)   ; to make it the new Y position.
  150.  
  151.                 rts
  152. *
  153. * --------------------------------------------------------------------------
  154.  
  155. * --------------------------------------------------------------------------
  156. * GetXY:
  157. * ------
  158. *
  159. * GETXY NEEDS:
  160. *
  161. * a0 - Pointer to an initialized WarpInfo structure.
  162. *
  163. * It returns the current X position in d0 and the current Y
  164. * position in d1.
  165. *
  166.  
  167. GetXY:          move.l  wi_CurLine(a0),d1   ; Get current Y addr
  168.                 sub.l   wi_WindowTop(a0),d1 ; Sub window to get Y offset.
  169.                 divu.w  wi_Modulo(a0),d1    ; Should not be a remainder.
  170.  
  171.                 moveq   #0,d0
  172.                 move.w  wi_CurX(a0),d0      ; Get current X position.
  173.  
  174.                 rts
  175. *
  176. * --------------------------------------------------------------------------
  177.  
  178. * --------------------------------------------------------------------------
  179. * WarpText:
  180. * ---------
  181. *
  182. * WARPTEXT NEEDS:
  183. *
  184. * d0 - Number of characters to type. (count)
  185. *
  186. * a0 - Pointer to an initialized WarpInfo structure.  (See InitWarpInfo)
  187. * a1 - Address of string of characters to type.
  188. *
  189. * REGISTER USAGE FOR WARPTEXT:  (All regs preserved but d0 which will be 0)
  190. *
  191. * d0 - Number of characters to type (count)
  192. * d1 - Character to be emitted
  193. * d2 - LoChar
  194. * d3 - HiChar
  195. * d4 - Current X position
  196. * d5 - Scratch
  197. * d7 - Bitplane modulo: add to get to next raster line in bitplane.
  198. *
  199. * a0 - Pointer to WarpInfo structure
  200. * a1 - Address of string of characters to type
  201. * a2 - Pointer to TextFont structure, address of tf_CharData
  202. * a3 - Addr of Current line.
  203. * a4 - Scratch
  204. * a5 - Scratch
  205. *
  206. * STACK USAGE FOR WARPTEXT:
  207. *
  208. *  0(sp) - Last line
  209. *  4(sp) - Top line
  210. *  8(sp) - tf_YSize
  211. * 12(sp) - tf_Modulo: add it to get to next line in font data
  212. * 16(sp) - wi_Modulo: add it to get to next line in bitplane 'window'
  213. * 20(sp) - Maximum (last) possible X position on a line
  214. *
  215.  
  216. sp_LastLine:    equ     0   ; Offsets into stack to get at this data.
  217. sp_TopLine:     equ     4
  218. sp_YSize:       equ     8
  219. sp_tf_Mod:      equ     12
  220. sp_wi_Mod:      equ     16
  221. sp_LastX:       equ     20
  222.  
  223. NoChar:         equ     256 ; I thought this was where the "empty-box"
  224.                             ; character was.  It isn't.  Anyone know where
  225.                             ; it is?  Or am I supposed to generate it
  226.                             ; myself????
  227.  
  228. WarpText:   movem.l d1-d5/d7/a2-a5,-(sp)
  229.  
  230.             moveq   #0,d4
  231.             move.w  wi_CurX(a0),d4      ; Get current X position.
  232.  
  233.             moveq   #0,d5
  234.             move.w  wi_LastX(a0),d5     ; Get maximum X position.
  235.             move.l  d5,-(sp)            ; Stick it on stack.  (1st item)
  236.  
  237.             move.w  wi_Modulo(a0),d5    ; Get wi_Modulo.
  238.             move.l  d5,-(sp)            ; Stick it on stack.  (2nd item)
  239.  
  240.             move.l  wi_TextFont(a0),a2  ; Use TextFont to get some stuff:
  241.  
  242.               moveq   #0,d2
  243.               move.b  tf_LoChar(a2),d2    ; Get tf_LoChar.
  244.  
  245.               moveq   #0,d3
  246.               move.b  tf_HiChar(a2),d3    ; Get tf_HiChar.
  247.  
  248.               move.w  tf_Modulo(a2),d5    ; Get tf_Modulo.
  249.               move.l  d5,-(sp)            ; Stick it on stack.  (3rd item)
  250.  
  251.               move.w  tf_YSize(a2),d5     ; Get tf_YSize
  252.               move.l  d5,-(sp)            ; Stick it on stack.  (4th item)
  253.  
  254.               move.l  tf_CharData(a2),a2  ; Replace textfont w/ tf_Chardata.
  255.  
  256.             move.l  wi_WindowTop(a0),a4 ; Get addr of wi_WindowTop.
  257.             move.l  a4,-(sp)            ; Stick it on stack.  (5th item)
  258.  
  259.             move.l  wi_LastLine(a0),a4  ; Get addr of wi_LastLine.
  260.             move.l  a4,-(sp)            ; Stick it on stack.  (6th item)
  261.  
  262.             move.l  wi_CurLine(a0),a3   ; Get addr of wi_CurLine.
  263.  
  264.             moveq   #0,d7
  265.             move.w  wi_BPMod(a0),d7     ; Get wi_BPMod.
  266.  
  267.             subq    #1,d0               ; Take one from count.
  268.             moveq   #0,d1               ; Clear d1 because using .b size.
  269.             subq    #1,d4               ; Take one from Current X.
  270.  
  271. DoNextChar:   addq    #1,d4               ; Add 1 to Current X.
  272. DoNextSinAdd: move.b  (a1)+,d1            ; Move char to emit to d1.
  273.               cmpi.b  #32,d1              ; Is it a space?
  274.                beq     Blank
  275.               cmp.b   d2,d1               ; Compare with LoChar.
  276.                blt     BoffoChar           ; May be a LF, FF, CR, etc.
  277.               cmp.b   d3,d1               ; Compare with HiChar.
  278.                blt     DoNoChar
  279.  
  280.               move.l  a2,a4               ; Copy tf_CharData to scratch.
  281.               sub.l   d2,d1               ; Sub LoChar from char.
  282.               adda.l  d1,a4               ; Add char to tf_CharData.
  283.  
  284. DoChar:       move.l  a3,a5               ; Copy current line to scratch.
  285.               adda.l  d4,a5               ; Add XPos to current line.
  286.  
  287.               move.l  sp_YSize(sp),d5     ; YSize is loop count.
  288.               subq.l  #1,d5
  289. MoveChar:       move.b  (a4),(a5)           ; Move line of char to bitplane.
  290.                 adda.l  sp_tf_Mod(sp),a4    ; Add tf_Modulo to tf_Chardata.
  291.                 adda.l  d7,a5               ; Add wi_BPMod to bitplane.
  292.                  dbra    d5,MoveChar
  293.  
  294. Blank:        cmp.l   sp_LastX(sp),d4     ; Compare max X and Current X...
  295.                blt     GotoDoNext          ; Do next if current < max.
  296.  
  297. DoLF:         moveq   #0,d4               ; Xpos is zero now.
  298.  
  299. DoCR:         cmpa.l  (sp),a3             ; CMP sp_LastLine with current.
  300.                beq     GotoNSA             ; Wrap on line if equ.
  301.  
  302.               adda.l  sp_wi_Mod(sp),a3    ; Point at next line.
  303.                bra     GotoNSA             ; Do another character.
  304.  
  305. DoNoChar:   move.l  a2,a4               ; Copy tf_Chardata to scratch.
  306.             add.l   #NoChar,a4          ; Point at empty-box char.
  307.              bra     DoChar              ; Do the empty-box char.
  308.  
  309. BoffoChar:  cmpi.l  #10,d1              ; Is is a linefeed?
  310.              beq     DoLF
  311.             cmpi.l  #12,d1              ; Is it a formfeed?
  312.              beq     DoFF
  313.             cmpi.l  #13,d1              ; Is it a CR?
  314.              beq     DoCR
  315.              bra     DoNoChar           ; Fine. Put up the box.
  316.  
  317. DoFF:       moveq   #0,d4               ; Make X pos zero.  |  It doesn't
  318.             move.l  sp_TopLine(sp),a3   ; Point at top      |  CLS yet.
  319.              bra     GotoNSA
  320.  
  321. GotoDoNext: dbra    d0,DoNextChar       ; Keep looping?
  322.              bra     WindUp              ; Loop is done. Clean up & bail.
  323.  
  324. GotoNSA:    dbra    d0,DoNextSinAdd     ; Do NextChar without adding.
  325.  
  326. WindUp:     addq.l  #8,sp               ; Get rid of stuff kept on stack.
  327.             addq.l  #8,sp
  328.             addq.l  #8,sp
  329.  
  330.             move.w  d4,wi_CurX(a0)      ; Store current X for next time.
  331.             move.l  a3,wi_CurLine(a0)   ; Store current Y for next time.
  332.  
  333.             movem.l (sp)+,d1-d5/d7/a2-a5
  334.  
  335.             rts
  336. *
  337. * ==========================================================================
  338.  
  339. * ==========================================================================
  340. *
  341. *        |             ___                        __     __     |
  342. *        |     /|  /  /     /   /    /   /  /|   /  \   /  \    |
  343. *       \|/   / | /  /---  / / /    / / /  /_|  /\__/  /\__/   \|/
  344. *        V   /  |/  /___   \/\/     \/\/  /  | /   \  /         V
  345. *
  346. * --------------------------------------------------------------------------
  347. * SetupFont:
  348. * ----------
  349. * Call with NewWarpInfo and TextFont on the stack.
  350. * (TextFont should be on top)
  351. *
  352. * You must allocate a 2048 byte buffer (does not have to reside in CHIP RAM)
  353. * and store its address into the nwi_FontData field of the NewWarpInfo
  354. * structure prior to calling SetupFont.
  355. * SetupFont will take the font data from the pointer to the FontData
  356. * structure you supply on the stack and rearrange it into the 2048 byte
  357. * array.  It is not a smart routine -- it is set up to unpack only the
  358. * Topaz 8 font, or any 8x8 font with the same number of characters as topaz
  359. * and the same modulo.  If you want to use an 8x8 font that has different
  360. * number of characters defined and a different modulo, you will have to
  361. * modify the SetupFont code.
  362. *
  363.  
  364. SetupFont:  movem.l     d0/a0-a3,-(sp)      ;Save used regs
  365.  
  366.             move.l      24(sp),a2           ;FontData kept in a2
  367.             move.l      28(sp),a1           ;NewWarpInfo kept in a1
  368.             move.l      nwi_FontData(a1),a0 ;array to rearrange font into
  369.  
  370.             move.l      #31,d0              ;number of blank chars.
  371. TheUnCola:  move.b      #$FE,(a0)+          ;$FE = %11111110
  372.             move.b      #$C6,(a0)+          ;$C6 = %11000110
  373.             move.b      #$C6,(a0)+          ;$C6 = %11000110
  374.             move.b      #$C6,(a0)+          ;$C6 = %11000110
  375.             move.b      #$C6,(a0)+          ;$C6 = %11000110
  376.             move.b      #$C6,(a0)+          ;$C6 = %11000110
  377.             move.b      #$FE,(a0)+          ;$FE = %11111110
  378.             move.b      #$00,(a0)+          ;$00 = %00000000
  379.              dbf         d0,TheUnCola       ;Get the picture? :-)
  380.  
  381.             move.l      tf_CharData(a2),a2  ;get addr of the font data
  382.             move.l      a2,a3               ;save for later loops
  383.             moveq       #0,d0               ;zero is 1st char in chardata
  384.  
  385. DoAnother:  add.w       d0,a2               ;add char offset to chardata
  386.  
  387.             move.b      (a2),(a0)+          ;begin copying char into array
  388.             add.w       #192,a2             ;add tf_modulo for next byte
  389.             move.b      (a2),(a0)+
  390.             add.w       #192,a2
  391.             move.b      (a2),(a0)+
  392.             add.w       #192,a2
  393.             move.b      (a2),(a0)+
  394.             add.w       #192,a2
  395.             move.b      (a2),(a0)+
  396.             add.w       #192,a2
  397.             move.b      (a2),(a0)+
  398.             add.w       #192,a2
  399.             move.b      (a2),(a0)+
  400.             add.w       #192,a2
  401.             move.b      (a2),(a0)+          ;finished copying this character
  402.  
  403.             move.l      a3,a2               ;point to chardata again
  404.             addq.b      #1,d0               ;add one for next character
  405.             cmp.w       #223,d0             ;need to stop after 223rd char
  406.              ble.s       DoAnother
  407.  
  408.             movem.l     (sp)+,d0/a0-a3      ;restore used regs
  409.  
  410.             rts
  411. *
  412. * --------------------------------------------------------------------------
  413.  
  414. * --------------------------------------------------------------------------
  415. * NewWarp:
  416. * --------
  417. * Call with NewWarpInfo, String-address, and String-count on the stack.
  418. * (String-count should be on top)
  419. *
  420. * You must have called SetupFont AND have filled in the nwi_BitPlane
  421. * field in the NewWarpInfo structure before you call NewWarp.
  422. * It would be a good idea, also, to make sure you've set up nwi_XLoc
  423. * and nwi_YLoc to the correct places before you go writing text.
  424. * They are character-position relative, rather than pixel relative.
  425. * Setting nwi_XLoc and nwi_XLoc to 8,8 for example, would be like telling
  426. * the Graphics library Text() routine to write text at 80,80.
  427. * Another note: Unlike Text(), NewWarp writes directly into a bitplane
  428. * and does not do clipping at the edges of rastports.  This makes
  429. * NewWarp very fast, but less flexible.  I have found it easiest to
  430. * use the WarpText routines in SUPER_BITMAP windows.
  431. *
  432.  
  433. NewWarp:    movem.l     d0-d3/a0-a4,-(sp)   ;save used registers
  434.  
  435.             move.l      40(sp),d3           ;String-count kept in d3
  436.             move.l      44(sp),a2           ;String-addr kept in a2
  437.             move.l      48(sp),a4           ;NewWarpInfo kept in a4
  438.  
  439.             move.w      nwi_XLoc(a4),d0     ;move to d0 before incrementing
  440.  
  441.             add.w       d3,nwi_XLoc(a4)     ;increment XLoc like Text()
  442.             subq.w      #1,d3               ;adjust count for dbf
  443.  
  444.             move.w      nwi_YLoc(a4),d1
  445.             move.l      nwi_BitPlane(a4),a0
  446.             move.l      nwi_FontData(a4),a1
  447.             move.l      a1,a3               ;safe keeping of FontData
  448.  
  449.             asl.w       #7,d1               ;This multiplies YLoc
  450.             move.w      d1,d2               ;times 640 in 26 cycles
  451.             asl.w       #2,d1               ;instead of the 74 cycles
  452.             add.w       d2,d1               ;a MULU would take.
  453.  
  454.             add.w       d0,d1               ;Add XLOC to expanded YLOC.
  455.             add.w       d1,a0               ;Add LOC offset to bitplane.
  456.  
  457. OnceAgain:  moveq       #0,d0
  458.             move.b      (a2)+,d0            ;Put character in d0.
  459.             asl.w       #3,d0               ;Make offset into FontData
  460.             add.w       d0,a1               ;Add offset to fontData address.
  461.  
  462.             move.b      (a1)+,(a0)          ;Start moving the font data
  463.             add.w       #80,a0              ;into the bitmap...
  464.             move.b      (a1)+,(a0)
  465.             add.w       #80,a0
  466.             move.b      (a1)+,(a0)
  467.             add.w       #80,a0
  468.             move.b      (a1)+,(a0)
  469.             add.w       #80,a0
  470.             move.b      (a1)+,(a0)
  471.             add.w       #80,a0
  472.             move.b      (a1)+,(a0)
  473.             add.w       #80,a0
  474.             move.b      (a1)+,(a0)
  475.             add.w       #80,a0
  476.             move.b      (a1)+,(a0)          ;Finished moving data.
  477.  
  478.             sub.w       #559,a0             ;restore a0 to next char loc
  479.             move.l      a3,a1               ;restore a1 to FontData
  480.  
  481.              dbf         d3,OnceAgain
  482.  
  483.             movem.l     (sp)+,d0-d3/a0-a4   ;restore used registers
  484.  
  485.             rts
  486. *
  487. * --------------------------------------------------------------------------
  488.  
  489. * --------------------------------------------------------------------------
  490. * XORCursor:
  491. * ----------
  492. * Call with NewWarpInfo on the stack.
  493. *
  494. * You must have called SetupFont AND have filled in the nwi_BitPlane
  495. * field in the NewWarpInfo structure before you call XORCursor.
  496. * XORCursor XOR's a console-device-like cursor to the current xy location.
  497. * To get the cursor to be a different color than the Text you've been
  498. * emitting with NewWarp you have to change the bitplane being pointed to
  499. * by nwi_BitPlane.  I thought of adding another APTR to the end of
  500. * the NewWarpInfo structure called nwi_CursorPlane that you could set
  501. * to point to a different bitplane which would only be used only
  502. * by XORCursor.  I haven't yet, as I want to get this stuff out.
  503. * If you would like to, feel free to do so.
  504. *
  505.  
  506. XORCursor:  movem.l     d0-d1/a0-a1,-(sp)   ;Save used registers
  507.  
  508.             move.l      20(sp),a1           ;NewWarpInfo kept in a1
  509.             move.w      nwi_YLoc(a1),d0
  510.             move.l      nwi_BitPlane(a1),a0
  511.  
  512.             asl.w       #7,d0               ;This multiplies YLoc
  513.             move.w      d0,d1               ;times 640 in 26 cycles
  514.             asl.w       #2,d0               ;instead of the 74 cycles
  515.             add.w       d1,d0               ;a MULU would take.
  516.  
  517.             add.w       nwi_XLoc(a1),d0     ;Add XLOC to expanded YLOC.
  518.             add.w       d0,a0               ;Add LOC offset to bitplane.
  519.  
  520.             eor.b       #$FF,(a0)           ;XOR the cursor...
  521.             add.w       #80,a0
  522.             eor.b       #$FF,(a0)
  523.             add.w       #80,a0
  524.             eor.b       #$FF,(a0)
  525.             add.w       #80,a0
  526.             eor.b       #$FF,(a0)
  527.             add.w       #80,a0
  528.             eor.b       #$FF,(a0)
  529.             add.w       #80,a0
  530.             eor.b       #$FF,(a0)
  531.             add.w       #80,a0
  532.             eor.b       #$FF,(a0)
  533.             add.w       #80,a0
  534.             eor.b       #$FF,(a0)
  535.  
  536.             movem.l     (sp)+,d0-d1/a0-a1   ;restore used registers
  537.  
  538.             rts
  539. *
  540. * ==========================================================================
  541.  
  542.             END     ; WarpText ends.
  543.  
  544. * --------------------- *
  545. * End of "WarpText.asm" *
  546. * --------------------- *
  547.